
#include "include/variant.h"
#include "name_table.h"

namespace qb {
namespace proto{

VariantRaw::VariantRaw()
{
    Data = NULL ;
    Length = 0 ;
    owned_ = false ;
}

VariantRaw::VariantRaw(const VariantRaw& raw)
{
    Data = NULL ;
    Length = 0 ;
    owned_ = false ;

    Copy(raw) ;
}

VariantRaw::~VariantRaw()
{
    Clear() ;
}

VariantRaw& VariantRaw::operator=(const VariantRaw& raw) 
{
    Copy(raw) ;
    return (*this) ;
}

bool VariantRaw::Copy(const VariantRaw& raw)
{
    return Copy(raw.Data , raw.Length) ;
}

bool VariantRaw::Copy(const void * buffer , size_t buflen)
{
    Clear() ;

    if(buffer == NULL || buflen == 0)
        return false;

    void * raw = malloc(buflen) ;
    if(raw == NULL)
        return false;

    memcpy(raw , buffer , buflen) ;
    Data = raw ;
    Length = buflen ;
    owned_ = true ;
    return true ;
}

void VariantRaw::Ref(const VariantRaw& raw)
{
    Clear() ;

    Data = raw.Data ;
    Length = raw.Length ;
    owned_ = false ;
}

void VariantRaw::Clear()
{
    if(owned_ == true)
    {
        if(Data != NULL)
        {
            ::free(Data) ;
        }
    }

    Data = NULL ;
    Length = 0 ;
    owned_ = false ;
}

VariantList::VariantList()
{
    variants_ = NULL ;
    size_ = 0 ;
    capacity_ = 0 ;
}

VariantList::VariantList(const VariantList& list)
{
    variants_ = NULL ;
    size_ = 0 ;
    capacity_ = 0 ;

    copy(list) ;
}

VariantList::~VariantList()
{
    clear() ;
}

bool VariantList::extend()
{
    if(variants_ == NULL)
    {
        //����ռ�
        size_t cap = 32 ;//Ĭ��32
        Variant ** vars = (Variant **)malloc(sizeof(Variant *) * cap) ;
        if(vars == NULL)
            return false;

        memset(vars , 0 , sizeof(Variant *) * cap) ;
        variants_ = vars ;
        capacity_ = cap ;
        size_ = 0 ;
    }

    if(size_ >= capacity_)
    {
        //�ռ䲻�㣬��������
        size_t cap = capacity_ + 16 ;       //��16�Ĳ�������
        Variant ** vars = (Variant **)malloc(sizeof(Variant *) * cap) ;
        if(vars == NULL)
            return false;

        memset(vars , 0 , sizeof(Variant *) * cap) ;

        for(size_t idx = 0 ; idx < size_ ; ++idx)
        {
            vars[idx] = variants_[idx] ;
        }

        ::free(variants_) ;
        capacity_ = cap ;
        variants_ = vars ;
    }

    return true ;
}

int VariantList::encodeAsTable(char* buf, int capcity)const
{
	if (buf == NULL || capcity <= 0)
		return -1;
	if (size() <= 0)
		return 0;
	VariantTable table;
	for (VariantList::const_iterator it = begin(); it != end(); ++it)
	{
		if (it->Type != Variant::VAR_MAP)
			return 0;
		const VariantMap& submap = *it;
		VariantRecord* record = table.addRecord();
		for (VariantMap::const_iterator mit = submap.begin(); mit != submap.end(); ++mit)
		{
			const Variant& val = *(mit->second);
			switch (val.Type)
			{
			case Variant::VAR_BOOL:record->setInt64(mit->first, (bool)val); break;
			case Variant::VAR_INT8:record->setInt64(mit->first, (int8_t)val); break;
			case Variant::VAR_UINT8:record->setInt64(mit->first, (uint8_t)val); break;
			case Variant::VAR_INT16:record->setInt64(mit->first, (int16_t)val); break;
			case Variant::VAR_UINT16:record->setInt64(mit->first, (uint16_t)val); break;
			case Variant::VAR_INT32:record->setInt64(mit->first, (int32_t)val); break;
			case Variant::VAR_UINT32:record->setInt64(mit->first, (uint32_t)val); break;
			case Variant::VAR_INT64:record->setInt64(mit->first, (int64_t)val); break;
			case Variant::VAR_UINT64:record->setInt64(mit->first, (uint64_t)val); break;
			case Variant::VAR_FLOAT:record->setDouble(mit->first, (float)val); break;
			case Variant::VAR_DOUBLE:record->setDouble(mit->first, (double)val); break;
			case Variant::VAR_STRING:{
				std::string str; val.GetString(str);
				record->setString(mit->first, str);
				break;
			}
			default:
				return 0;//��֧�ֵĸ�ʽ,����list<map>ģʽ
				break;
			}
		}
	}
	int size = table.encode();
	if (size <= capcity)
	{
		memcpy(buf, table.c_str(), size);
		return size;
	}
	return 0 - size;
}

void VariantList::push_back(const Variant& var)
{
    if(extend() == false)
        return ;

    Variant * n = new Variant() ;
    *n = var ;

    variants_[size_++] = n ;
}

VariantMap * VariantList::add_map()
{
    if(extend() == false)
        return  NULL ;

    VariantMap * map = new VariantMap() ;
    Variant * n = new Variant() ;

    n->Type = Variant::VAR_MAP ;
    n->Data.raw = map ;

    variants_[size_++] = n ;
    return map ;
}

VariantList* VariantList::add_list()
{
    if(extend() == false)
        return  NULL ;

    VariantList * list = new VariantList() ;
    Variant * n = new Variant() ;

    n->Type = Variant::VAR_LIST ;
    n->Data.raw = list ;

    variants_[size_++] = n ;
    return list ;
}

Variant* VariantList::add_variant()
{
    if(extend() == false)
        return  NULL ;

    Variant * n = new Variant() ;

    n->Type = Variant::VAR_UNKNOWN ;

    variants_[size_++] = n ;
    return n ;
}


VariantList& VariantList::operator=(const VariantList& list)
{
    copy(list) ;
    return (*this) ;
}

void VariantList::clear()
{
    for(size_t idx = 0 ; idx < size_ ; ++idx)
    {
        Variant * var = variants_[idx] ;
        if(var != NULL)
        {
            delete var ;
        }
    }

    if(variants_ != NULL)
    {
        ::free(variants_) ;
    }

    variants_ = NULL; 
    size_ = 0 ;
    capacity_ = 0 ;
}

VariantList::const_iterator::const_iterator()
{
    variants_ = NULL ;
    index_ = -1 ;
    size_ = 0 ;
}

VariantList::const_iterator::const_iterator(const VariantList::const_iterator& iter)
{
    variants_ = iter.variants_ ;
    index_ = iter.index_ ;
    size_ = iter.size_ ;
}

VariantList::const_iterator::const_iterator(const VariantList::iterator& iter)
{
    variants_ = iter.variants_ ;
    index_ = iter.index_ ;
    size_ = iter.size_ ;
}

VariantList::const_iterator& VariantList::const_iterator::operator=(const const_iterator& iter)
{
    variants_ = iter.variants_ ;
    index_ = iter.index_ ;
    size_ = iter.size_ ;

    return (*this) ;
}

bool VariantList::const_iterator::operator==(const const_iterator& iter) const
{
    if(variants_ == iter.variants_ && index_ == iter.index_ && size_ == iter.size_)
        return true ;
    else
        return false ;
}

bool VariantList::const_iterator::operator!=(const const_iterator& iter) const
{
    return !((*this) == iter) ;
}

bool VariantList::const_iterator::operator==(const VariantList::iterator& iter) const
{
    if(variants_ == iter.variants_ && index_ == iter.index_ && size_ == iter.size_)
        return true ;
    else
        return false ;
}

bool VariantList::const_iterator::operator!=(const VariantList::iterator& iter) const
{
    return !((*this) == iter) ;
}

const Variant * VariantList::const_iterator::operator->() const
{
    return variants_[index_] ;
}

const Variant& VariantList::const_iterator::operator*() const
{
    const Variant * var = NULL ;
    
    if(variants_ != NULL)
    {
        var = variants_[index_] ;
    }

    if(var == NULL)
        return Variant::EMPTY ;
    else
        return *var ;
}

VariantList::const_iterator VariantList::const_iterator::operator++()
{
    ++index_ ;
    return (*this) ;
}

VariantList::const_iterator VariantList::const_iterator::operator++(int step)
{
    if(step == 0)
        step = 1 ;

    index_ += step ;
    return (*this) ;
}

VariantList::const_iterator VariantList::const_iterator::operator--()
{
    --index_ ;
    return (*this) ;
}

VariantList::const_iterator VariantList::const_iterator::operator--(int step) 
{
    if(step == 0)
        step = 1 ;

    index_ -= step ;
    return (*this) ;
}

VariantList::iterator::iterator()
{
    variants_ = NULL ;
    index_ = 0 ;
}

VariantList::iterator& VariantList::iterator::operator=(const iterator& iter)
{
    variants_ = iter.variants_ ;
    index_ = iter.index_ ;

    return (*this) ;
}

bool VariantList::iterator::operator==(const iterator& iter) const
{
    if(variants_ == iter.variants_ && index_ == iter.index_)
        return true ;
    else
        return false ;
}

bool VariantList::iterator::operator!=(const iterator& iter) const
{
    return !((*this) == iter) ;
}

Variant * VariantList::iterator::operator->()
{
    return variants_[index_] ;
}

Variant& VariantList::iterator::operator*()
{
    Variant * var = variants_[index_] ;
    return *var ;
}

VariantList::iterator VariantList::iterator::operator++()
{
    ++index_ ;
    return (*this) ;
}

VariantList::iterator VariantList::iterator::operator++(int step)
{
    if(step == 0)
        step = 1 ;

    index_ += step ;
    return (*this) ;
}

VariantList::iterator VariantList::iterator::operator--()
{
    --index_ ;
    return (*this) ;
}

VariantList::iterator VariantList::iterator::operator--(int step)
{
    if(step == 0)
        step = 1 ;

    index_ -= step ;
    return (*this) ;
}


VariantList::const_iterator VariantList::begin() const
{
    const_iterator iter ;
    iter.variants_ = variants_ ;
    iter.index_ = 0 ;
    iter.size_ = size_ ;

    return iter ;
}

VariantList::iterator VariantList::begin()
{
    iterator iter ;
    iter.variants_ = variants_ ;
    iter.index_ = 0 ;
    iter.size_ = size_ ;

    return iter ;
}

VariantList::const_iterator VariantList::end() const
{
    const_iterator iter ;
    iter.variants_ = variants_ ;
    iter.index_ = size_ ;
    iter.size_ = size_ ;

    return iter ;
}

VariantList::iterator VariantList::end()
{
    iterator iter ;
    iter.variants_ = variants_ ;
    iter.index_ = size_ ;
    iter.size_ = size_ ;

    return iter ;
}

const VariantList VariantList::EMPTY ;

void VariantList::copy(const VariantList& list)
{
    clear() ;

    size_t cap = list.capacity_ ;
    if(cap == 0)
        return ;

    size_t len = sizeof(Variant *) * cap ;
    Variant ** vars = (Variant **)malloc(len) ;
    if(vars == NULL)
        return ;

    memset(vars , 0 , len) ;
    for(size_t idx = 0 ; idx < list.size_ ; ++idx)
    {
        Variant * var = new Variant() ;
        *var = *(list.variants_[idx]) ;
        vars[idx] = var ;
    }

    variants_ = vars ;
    capacity_ = cap ;
    size_ = list.size() ;
}

VariantMap::VariantMapItem::VariantMapItem() 
{
    first = NULL ;
    second = NULL ;
}

VariantMap::VariantMapItem::VariantMapItem(const char *name , Variant * data)
{
    first = NULL ;
    second = NULL ;

    Value(name , data) ;
}

VariantMap::VariantMapItem::~VariantMapItem() 
{
    Final() ;
}

void VariantMap::VariantMapItem::Final() 
{
    if(first != NULL)
        ::free(first) ;

    if(second != NULL)
        delete second ;

    first = NULL ;
    second = NULL ;
}

void VariantMap::VariantMapItem::Value(const char * name , Variant * data)
{
    size_t len = ::strlen(name);
    char * str = (char *)malloc(len + 1) ;
    memcpy(str , name , len) ;
    str[len] = '\0' ;

    first = str ; 
    second = data ;
}

void VariantMap::VariantMapItem::Value(const char * name , size_t nlen , Variant * data) 
{
    if(name == NULL || nlen == 0)
        return ;

    size_t len = nlen ;
    if(name[nlen - 1] != '\0')
        ++len ;
    char * str = (char *)malloc(len) ;
    memcpy(str , name , nlen) ;
    str[len - 1] = '\0' ;

    first = str ; 
    second = data ;

}


VariantMap::const_iterator::const_iterator()
{
    items_ = NULL ;
    index_ = -1 ;
    size_ = 0 ;
}

VariantMap::const_iterator& VariantMap::const_iterator::operator=(const VariantMap::const_iterator& iter)
{
    items_ = iter.items_ ;
    index_ = iter.index_ ;
    size_ = iter.size_ ;

    return (*this) ;
}

VariantMap::const_iterator::const_iterator(const VariantMap::iterator& iter)
{
    items_ = iter.items_ ;
    index_ = iter.index_ ;
    size_ = iter.size_ ;
}

VariantMap::const_iterator& VariantMap::const_iterator::operator=(const VariantMap::iterator& iter)
{
    items_ = iter.items_ ;
    index_ = iter.index_ ;
    size_ = iter.size_ ;

    return (*this) ;
}

bool VariantMap::const_iterator::operator==(const VariantMap::const_iterator& iter) const
{
    if(items_ == iter.items_ && index_ == iter.index_ && size_ == iter.size_)
        return true ;
    else
        return false ;
}

bool VariantMap::const_iterator::operator!=(const VariantMap::const_iterator& iter) const
{
    return !((*this) == iter) ;
}

bool VariantMap::const_iterator::operator==(const VariantMap::iterator& iter) const
{
    if(items_ == iter.items_ && index_ == iter.index_ && size_ == iter.size_)
        return true ;
    else
        return false ;
}

bool VariantMap::const_iterator::operator!=(const VariantMap::iterator& iter) const
{
    return !((*this) == iter) ;
}

const VariantMap::Item* VariantMap::const_iterator::operator->() const
{
    return items_ + index_ ;
}

VariantMap::const_iterator VariantMap::const_iterator::operator++()
{
    ++index_ ;
    return (*this) ;
}

VariantMap::const_iterator VariantMap::const_iterator::operator++(int step)
{
    index_ += step ;
    return (*this) ;
}

VariantMap::const_iterator VariantMap::const_iterator::operator--()
{
    --index_ ;
    return (*this) ;
}

VariantMap::const_iterator VariantMap::const_iterator::operator--(int step) 
{
    index_ -= step ;
    return (*this) ;
}

VariantMap::iterator::iterator()
{
    items_ = NULL ;
    index_ = -1 ;
    size_ = 0 ;
}

VariantMap::iterator& VariantMap::iterator::operator=(const iterator& iter)
{
    items_ = iter.items_ ;
    index_ = iter.index_ ;
    size_ = iter.size_ ;

    return (*this) ;
}

bool VariantMap::iterator::operator==(const iterator& iter) const
{
    if(items_ == iter.items_ && index_ == iter.index_ && size_ == iter.size_)
        return true ;
    else
        return false ;
}

bool VariantMap::iterator::operator!=(const iterator& iter) const
{
    return !((*this) == iter) ;
}

VariantMap::Item* VariantMap::iterator::operator->()
{
    return items_ + index_ ;
}
VariantMap::iterator VariantMap::iterator::operator++()
{
    ++index_ ;
    return (*this) ;
}

VariantMap::iterator VariantMap::iterator::operator++(int step)
{
    index_ += step ;
    return (*this) ;
}

VariantMap::iterator VariantMap::iterator::operator--()
{
    --index_ ;
    return (*this) ;
}

VariantMap::iterator VariantMap::iterator::operator--(int step)
{
    index_ -= step ;
    return (*this) ;
}


VariantMap::const_iterator VariantMap::begin() const
{
    const_iterator iter ;
    iter.items_ = items_ ;
    iter.index_ = 0 ;
    iter.size_ = size_ ;

    return iter ;
}

VariantMap::iterator VariantMap::begin()
{
    iterator iter ;
    iter.items_ = items_ ;
    iter.index_ = 0 ;
    iter.size_ = size_ ;

    return iter ;
}

VariantMap::const_iterator VariantMap::end() const
{
    const_iterator iter ;
    iter.items_ = items_ ;
    iter.index_ = size_ ;
    iter.size_ = size_ ;
    return iter ;
}

VariantMap::iterator VariantMap::end()
{
    iterator iter ;
    iter.items_ = items_ ;
    iter.index_ = size_ ;
    iter.size_ = size_ ;
    return iter ;
}

VariantMap::VariantMap()
{
    items_ = NULL ;
    size_ = 0 ;
    capacity_ = 0 ;

    name_table_ = NULL ;
    item_changed_ = false ;
}

VariantMap::VariantMap(const VariantMap& map)
{
    items_ = NULL ;
    size_ = 0 ;
    capacity_ = 0 ;

    name_table_ = NULL ;
    item_changed_ = false ;

    copy(map) ;
}

VariantMap::~VariantMap()
{
    clear() ;
}

VariantMap& VariantMap::operator=(const VariantMap& map) 
{
    copy(map) ;
    return (*this) ;
}

bool VariantMap::set_value(const char * name , Variant * var) 
{
    if(extend() == false)
    {
        delete var ;
        return false;
    }

    items_[size_++].Value(name , var) ;

    item_changed_ = true ;
    return true ;
}

bool VariantMap::set_value(const char * name , size_t nlen , Variant * var)
{
    if(extend() == false)
    {
        delete var ;
        return false;
    }

    items_[size_++].Value(name , nlen , var) ;

    item_changed_ = true ;
    return true ;
}

void VariantMap::SetBool(const char *name, bool value)
{
    set_value(name , new Variant(value)) ;
}

void VariantMap::SetUInt8(const char *name, uint8_t value)
{
    set_value(name , new Variant(value)) ;
}

void VariantMap::SetUInt16(const char *name, uint16_t value)
{
    set_value(name , new Variant(value)) ;
}

void VariantMap::SetUInt32(const char *name, uint32_t value)
{
    set_value(name , new Variant(value)) ;
}

void VariantMap::SetUInt64(const char *name, uint64_t value)
{
    set_value(name , new Variant(value)) ;
}

void VariantMap::SetInt8(const char *name, int8_t value)
{
    set_value(name , new Variant(value)) ;
}

void VariantMap::SetInt16(const char *name, int16_t value)
{
    set_value(name , new Variant(value)) ;
}

void VariantMap::SetInt32(const char *name, int32_t value)
{
    set_value(name , new Variant(value)) ;
}

void VariantMap::SetInt64(const char *name, int64_t value)
{
    set_value(name , new Variant(value)) ;
}

void VariantMap::SetFloat(const char *name, float value)
{
    set_value(name , new Variant(value)) ;
}

void VariantMap::SetDouble(const char *name, double value)
{
    set_value(name , new Variant(value)) ;
}

void VariantMap::SetString(const char *name, const std::string &value)
{
    set_value(name , new Variant(value)) ;
}

void VariantMap::SetRaw(const char *name, const char *value, size_t size)
{
    set_value(name , new Variant(value , size)) ;
}

void VariantMap::SetMap(const char *name , const VariantMap& map) 
{
    set_value(name , new Variant(map)) ;
}

void VariantMap::SetList(const char *name , const VariantList& list) 
{
    set_value(name , new Variant(list)) ;
}

VariantMap* VariantMap::AddMap(const char *name)
{
    VariantMap *map = new VariantMap();
    Variant * var = new Variant() ;
    var->Type = Variant::VAR_MAP ;
    var->Length = 0 ;
    var->Data.raw = map ;

    if(set_value(name , var) == false)
        return NULL ;

    return map ;
}

VariantList* VariantMap::AddList(const char *name)
{
    VariantList *list = new VariantList();
    Variant * var = new Variant() ;
    var->Type = Variant::VAR_LIST ;
    var->Length = 0 ;
    var->Data.raw = list ;

    if(set_value(name , var) == false)
        return NULL ;
    return list ;
}
VariantTable* VariantMap::AddTable(const char* name)
{
	VariantTable *table = new VariantTable();
	Variant * var = new Variant();
	var->Type = Variant::VAR_TABLE;
	var->Length = 0;
	var->Data.raw = table;

	if (set_value(name, var) == false)
		return NULL;
	return table;
}
Variant* VariantMap::AddVariant(const char *name)
{
    Variant * var = new Variant() ;
    if(set_value(name , var) == false)
        return NULL ;
    return var ;
}

Variant* VariantMap::AddVariant(const char *name , size_t nlen)
{
    Variant * var = new Variant() ;
    if(set_value(name , nlen , var) == false)
        return NULL ;
    return var ;
}

void VariantMap::rebuild_name_table()
{
    item_changed_ = true ;
    build_name_table() ;
}

bool VariantMap::build_name_table() const
{
    if(item_changed_ == false)
        return true ;

    if(name_table_ == NULL)
    {
        name_table_ = new name_table() ;
    }
    else
    {
        name_table_->clear() ;
    }

    for(size_t idx = 0 ; idx < size_ ; ++idx)
    {
        Item& item = items_[idx] ;
        if(item.first == NULL)
            continue ;

        name_table_->insert(item.first , idx) ;    
    }

    item_changed_ = false ;
    return true ;
}
bool VariantMap::getValue(const char* name, const Variant*& var)const
{
	return get_value(name, var);
}
bool VariantMap::get_value(const char * name , const Variant*& var) const
{
    if(build_name_table() == false || name_table_ == NULL || name == NULL)
        return false ;

    size_t value = 0 ;
    if(name_table_->find(name , value) == false)
        return false ;

    var = items_[value].second ;
    return true ;
}

bool VariantMap::GetBool(const char *name, bool &value) const
{
    //value = false ;

    const Variant * var = NULL ;
    if(get_value(name , var) == false)
        return false ;

    if(var->Type != Variant::VAR_BOOL)
        return false ;

    return var->GetBool(value) ;
}

bool VariantMap::GetUInt8(const char *name, uint8_t &value) const
{
    //value = 0 ;
    const Variant * var = NULL ;
    if(get_value(name , var) == false)
        return false ;

    if(var->Type != Variant::VAR_UINT8)
        return false ;

    return var->GetUInt8(value) ;
}

bool VariantMap::GetUInt16(const char *name, uint16_t &value) const
{
    //value = 0 ;
    const Variant * var = NULL ;
    if(get_value(name , var) == false)
        return false ;

    if(var->Type != Variant::VAR_UINT16)
        return false ;

    return var->GetUInt16(value) ;
}

bool VariantMap::GetUInt32(const char *name, uint32_t &value) const
{
    //value = 0 ;
    const Variant * var = NULL ;
    if(get_value(name , var) == false)
        return false ;

    if(var->Type != Variant::VAR_UINT32)
        return false ;

    return var->GetUInt32(value) ;
}

bool VariantMap::GetUInt64(const char *name, uint64_t &value) const
{
    //value = 0 ;
    const Variant * var = NULL ;
    if(get_value(name , var) == false)
        return false ;

    if(var->Type != Variant::VAR_UINT64)
        return false ;

    return var->GetUInt64(value) ;
}

bool VariantMap::GetInt8(const char *name, int8_t &value) const
{
    //value = 0 ;
    const Variant * var = NULL ;
    if(get_value(name , var) == false)
        return false ;

    if(var->Type != Variant::VAR_INT8)
        return false ;

    return var->GetInt8(value) ;
}

bool VariantMap::GetInt16(const char *name, int16_t &value) const
{
    //value = 0 ;
    const Variant * var = NULL ;
    if(get_value(name , var) == false)
        return false ;

    if(var->Type != Variant::VAR_INT16)
        return false ;

    return var->GetInt16(value) ;
}

bool VariantMap::GetInt32(const char *name, int32_t &value) const
{
    //value = 0 ;
    const Variant * var = NULL ;
    if(get_value(name , var) == false)
        return false ;

    if(var->Type != Variant::VAR_INT32)
        return false ;

    return var->GetInt32(value) ;
}

bool VariantMap::GetInt64(const char *name, int64_t &value) const
{
    //value = 0 ;
    const Variant * var = NULL ;
    if(get_value(name , var) == false)
        return false ;

    if(var->Type != Variant::VAR_INT64)
        return false ;

    return var->GetInt64(value) ;
}

bool VariantMap::GetFloat(const char *name, float &value) const
{
    //value = 0 ;
    const Variant * var = NULL ;
    if(get_value(name , var) == false)
        return false ;

    if(var->Type != Variant::VAR_FLOAT)
        return false ;

    return var->GetFloat(value) ;
}

bool VariantMap::GetDouble(const char *name, double &value) const
{
    //value = 0 ;
    const Variant * var = NULL ;
    if(get_value(name , var) == false)
        return false ;

    if(var->Type != Variant::VAR_DOUBLE)
        return false ;

    return var->GetDouble(value) ;
}

bool VariantMap::GetString(const char *name, std::string &value) const
{
    //value.clear() ;

    const Variant * var = NULL ;
    if(get_value(name , var) == false)
        return false ;

    if(var->Type != Variant::VAR_STRING && var->Type != Variant::VAR_RAW)
        return false ;

    return var->GetString(value) ;
}

/*
    �ڴ濽��ģʽ��size�����㹻��
*/
bool VariantMap::GetRaw(const char *name, VariantRaw& value) const
{
    const Variant * var = NULL ;
    if(get_value(name , var) == false)
        return false ;

    if(var->Type != Variant::VAR_RAW)
        return false ;


    const void * raw = NULL ;
    size_t size = 0 ;
    if(var->RefRaw(raw , size) == false)
        return false ;

    return value.Copy(raw , size) ;
}

bool VariantMap::GetMap(const char *name, VariantMap &value) const
{
    //value.clear() ;

    const Variant * var = NULL ;
    if(get_value(name , var) == false)
        return false ;

    if(var->Type != Variant::VAR_MAP)
        return false ;

    return var->GetMap(value) ;
}

bool VariantMap::GetList(const char * name , VariantList& value) const
{
    //value.clear() ;

    const Variant * var = NULL ;
    if(get_value(name , var) == false)
        return false ;

    if(var->Type != Variant::VAR_LIST)
        return false ;

    return var->GetList(value) ;
}

/*
    �ڴ�����ģʽ��������Message����֮ǰ���ͷ����á�
*/
bool VariantMap::RefString(const char *name, const char *& value, size_t &size) const
{
    //value = NULL ;
    //size = 0 ;

    const Variant * var = NULL ;
    if(get_value(name , var) == false)
        return false ;

    if(var->Type != Variant::VAR_STRING && var->Type != Variant::VAR_RAW)
        return false ;

    return var->RefString(value , size) ;
}

bool VariantMap::RefRaw(const char *name, const void *& value, size_t &size) const
{
    //value = NULL ;
    //size = 0 ;

    const Variant * var = NULL ;
    if(get_value(name , var) == false)
        return false ;

    if(var->Type != Variant::VAR_RAW)
        return false ;

    return var->RefRaw(value , size) ;
}

bool VariantMap::RefMap(const char *name, const VariantMap* &value) const
{
    //value = NULL ;

    const Variant * var = NULL ;
    if(get_value(name , var) == false)
        return false ;

    if(var->Type != Variant::VAR_MAP)
        return false ;

    return var->RefMap(value) ;
}

bool VariantMap::RefList(const char *name , const VariantList*& value) const
{
    //value = NULL ;
    const Variant * var = NULL ;
    if(get_value(name , var) == false)
        return false ;

    if(var->Type != Variant::VAR_LIST)
        return false ;

    return var->RefList(value) ;
}

Variant& VariantMap::operator[](const std::string& name)
{
    Variant * var = AddVariant(name.c_str()) ;
    return (*var) ;
}

Variant& VariantMap::operator[](const char * name)
{
    Variant * var = AddVariant(name) ;
    return (*var) ;
}

bool VariantMap::extend()
{
    if(items_ == NULL)
    {
        size_t cap = 32 ;
        Item * items = (Item *)malloc(sizeof(Item) * cap) ;
        if(items == NULL)
            return false ;

        memset(items , 0 , sizeof(Item) * cap) ;

        items_ = items ;
        size_ = 0 ;
        capacity_ = cap ;
    }

    if(size_ >= capacity_ - 1)
    {
        //û��ʣ��ռ䣬������չ
        size_t cap = capacity_ + 16 ;       //������16����
        Item * items = (Item *)malloc(sizeof(Item ) * cap) ;
        if(items == NULL)
            return false ;

        memset(items , 0 , sizeof(Item) * cap) ;
        for(size_t idx = 0 ; idx < size_ ; ++idx) 
        {
            items[idx].first = items_[idx].first ;
            items[idx].second = items_[idx].second ;
        }

        ::free(items_) ;
        items_ = items ;
        capacity_ = cap ;
    }

    return true ;
}

void VariantMap::copy(const VariantMap& table)
{
    clear() ;

    uint32_t cap = table.capacity_ ;
    if(cap == 0 || table.items_ == NULL)
        return ;

    Item * items = (Item *)malloc(sizeof(Item) * cap) ;
    if(items == NULL)
        return ;

    memset(items , 0 , sizeof(Item *) * cap) ;

    for(size_t idx = 0 ; idx < table.size_ ; ++idx)
    {
        Item& item = table.items_[idx] ;
        if(item.first == NULL)
            continue ;

        items[idx].Value(item.first , new Variant(*(item.second))) ;
    }

    items_ = items ;
    capacity_ = cap ;
    size_ = table.size_ ;
    item_changed_ = true ;
    return ;
}

void VariantMap::clear()
{
    if(name_table_ != NULL)
    {
        delete name_table_ ;
        name_table_ = NULL ;
    }

    if(items_ != NULL)
    {
        for(size_t idx = 0 ; idx < size_ ; ++idx)
        {
            Item& item = items_[idx] ;
            item.Final() ;
        }

        ::free(items_) ;

        items_ = NULL ;
    }

    capacity_ = 0 ;
    size_ = 0 ;
    item_changed_ = false ;
}

const char * VariantMap::names(size_t index) const
{
    if(items_ == NULL || index >= capacity_)
        return NULL ;
    
    return items_[index].first ;
}

const Variant * VariantMap::values(size_t index) const
{
    if(items_ == NULL || index >= capacity_)
        return NULL ;
    
    return items_[index].second ;
}

Variant * VariantMap::values(size_t index)
{
    if(items_ == NULL || index >= capacity_)
        return NULL ;
    
    return items_[index].second ;
}

const VariantMap VariantMap::EMPTY ;
const VariantTable VariantTable::EMPTY;


Variant::Variant() 
{
    Type = VAR_UNKNOWN ;
    Length = 0 ;
    Data.val = 0 ;
}

void Variant::Clear()
{
    if(Type == VAR_STRING || Type == VAR_RAW)
    {
        void *  buffer = Data.raw ;
        if(buffer != NULL)
        {
            ::free(buffer) ;
        }

        Length = 0 ;
    }
    else if(Type == VAR_MAP)
    {
        Map * map = (Map *)Data.raw ;
        if(map != NULL)
        {
            delete map ;
        }
        Data.raw = NULL ;
    }
    else if(Type == VAR_LIST)
    {
        List * list = (List *)Data.raw ;
        if(list != NULL)
        {
            delete list ;
        }

        Data.raw = NULL ;
	}
	else if (Type == VAR_TABLE)
	{
		Table* table = (Table*)Data.raw;
		if (table != NULL)
			delete table;
		Data.raw = NULL;
	}
    Data.val = 0 ;
    Length = 0 ;
}

void Variant::Assign(const Variant& var)
{
    Clear() ;

    Type = var.Type ;
    Length = var.Length ;
    memcpy(&Data , &var.Data , sizeof(VariantData)) ;

    if(Type == VAR_STRING || Type == VAR_RAW)
    {
        if(Length == 0)
        {
            Data.val = 0 ;
            return ;
        }

        void *  buffer = malloc(Length) ;
        if(buffer == NULL)
        {
            Data.val = 0 ;
            return ;
        }

        memcpy(buffer ,  var.Data.raw , Length) ;
        Data.raw = buffer ;
    }
    else if(Type == VAR_MAP)
    {
        Map * map = new Map() ;

        *map = *((Map *)var.Data.raw) ;
        Data.raw = map ;    
    }
    else if(Type == VAR_LIST)
    {
        List * list = new List() ;
        *list = *((List *)var.Data.raw) ;
        Data.raw = list ;
	}
	else if (Type == VAR_TABLE)
	{
		Table * table = new Table();
		*table = *((Table *)var.Data.raw);
		Data.raw = table;
	}
}

Variant::Variant(const Variant& var)
{
    Type = VAR_UNKNOWN ;
    Length = 0 ;
    Data.val = 0 ;

    Assign(var) ;
}

Variant::Variant(VarType type)
{
    Type = type ;
    Length = 0 ;
    Data.val = 0 ;
}

Variant::Variant(bool val)
{
    Type = Variant::VAR_UNKNOWN ;
    Length = 0 ;
    Data.val = 0 ;

    SetBool(val) ;
}

Variant::Variant(int8_t val)
{
    Type = Variant::VAR_UNKNOWN ;
    Length = 0 ;
    Data.val = 0 ;

    SetInt8(val) ;
}

Variant::Variant(uint8_t val)
{
    Type = Variant::VAR_UNKNOWN ;
    Length = 0 ;
    Data.val = 0 ;

    SetUInt8(val) ;
}

Variant::Variant(int16_t val)
{
    Type = Variant::VAR_UNKNOWN ;
    Length = 0 ;
    Data.val = 0 ;

    SetInt16(val) ;
}

Variant::Variant(uint16_t val)
{
    Type = Variant::VAR_UNKNOWN ;
    Length = 0 ;
    Data.val = 0 ;

    SetUInt16(val) ;
}

Variant::Variant(int32_t val)
{
    Type = Variant::VAR_UNKNOWN ;
    Length = 0 ;
    Data.val = 0 ;

    SetInt32(val) ;
}

Variant::Variant(uint32_t val)
{
    Type = Variant::VAR_UNKNOWN ;
    Length = 0 ;
    Data.val = 0 ;

    SetUInt32(val) ;
}

Variant::Variant(int64_t val)
{
    Type = Variant::VAR_UNKNOWN ;
    Length = 0 ;
    Data.val = 0 ;

    SetInt64(val) ;
}

Variant::Variant(uint64_t val)
{
    Type = Variant::VAR_UNKNOWN ;
    Length = 0 ;
    Data.val = 0 ;

    SetUInt64(val) ;
}


Variant::Variant(float val)
{
    Type = Variant::VAR_UNKNOWN ;
    Length = 0 ;
    Data.val = 0 ;

    SetFloat(val) ;
}

Variant::Variant(double val)
{
    Type = Variant::VAR_UNKNOWN ;
    Length = 0 ;
    Data.val = 0 ;

    SetDouble(val) ;
}

Variant::Variant(const char * val)
{
    Type = Variant::VAR_UNKNOWN ;
    Length = 0 ;
    Data.val = 0 ;

    SetString(val) ;
}

Variant::Variant(const std::string& val)
{
    Type = Variant::VAR_UNKNOWN ;
    Length = 0 ;
    Data.val = 0 ;

    SetString(val) ;
}

Variant::Variant(const void * val , int len)
{
    Type = Variant::VAR_UNKNOWN ;
    Length = 0 ;
    Data.val = 0 ;

    SetRaw(val , len) ;
}

Variant::Variant(const Map& map)
{
    Type = Variant::VAR_UNKNOWN ;
    Length = 0 ;
    Data.val = 0 ;

    SetMap(map) ;
}

Variant::Variant(const List& list)
{
    Type = Variant::VAR_UNKNOWN ;
    Length = 0 ;
    Data.val = 0 ;

    SetList(list) ;
}

Variant::~Variant()
{
    Clear() ;
}

bool Variant::SetBool(bool val)
{
    if(Type == VAR_UNKNOWN)
    {
        Type = VAR_BOOL ;
    }

    if(Type != VAR_BOOL)
        return false ;

    Data.val = 0 ;
    Data.bv = val ;
    return true ;
}

bool Variant::SetInt8(int8_t val)
{
    if(Type == VAR_UNKNOWN)
    {
        Type = VAR_INT8 ;
    }

    if(Type != VAR_INT8)
        return false ;

    Data.val = 0 ;
    Data.i8 = val ;
    return true ;
}

bool Variant::SetUInt8(uint8_t val)
{
    if(Type == VAR_UNKNOWN)
    {
        Type = VAR_UINT8 ;
    }

    if(Type != VAR_UINT8)
        return false ;

    Data.val = 0 ;
    Data.u8 = val ;
    return true ;
}

bool Variant::SetInt16(int16_t val)
{
    if(Type == VAR_UNKNOWN)
    {
        Type = VAR_INT16 ;
    }

    if(Type != VAR_INT16)
        return false ;

    Data.val = 0 ;
    Data.i16 = val ;
    return true ;

}

bool Variant::SetUInt16(uint16_t val)
{
    if(Type == VAR_UNKNOWN)
    {
        Type = VAR_UINT16 ;
    }

    if(Type != VAR_UINT16)
        return false ;

    Data.val = 0 ;
    Data.u16 = val ;
    return true ;
}

bool Variant::SetInt32(int32_t val)
{
    if(Type == VAR_UNKNOWN)
    {
        Type = VAR_INT32 ;
    }

    if(Type != VAR_INT32)
        return false ;

    Data.val = 0 ;
    Data.i32 = val ;
    return true ;

}

bool Variant::SetUInt32(uint32_t val)
{
    if(Type == VAR_UNKNOWN)
    {
        Type = VAR_UINT32 ;
    }

    if(Type != VAR_UINT32)
        return false ;

    Data.val = 0 ;
    Data.u32 = val ;
    return true ;
}

bool Variant::SetInt64(int64_t val)
{
    if(Type == VAR_UNKNOWN)
    {
        Type = VAR_INT64 ;
    }

    if(Type != VAR_INT64)
        return false ;

    Data.val = 0 ;
    Data.i64 = val ;
    return true ;

}

bool Variant::SetUInt64(uint64_t val)
{
    if(Type == VAR_UNKNOWN)
    {
        Type = VAR_UINT64 ;
    }

    if(Type != VAR_UINT64)
        return false ;

    Data.val = 0 ;
    Data.u64 = val ;
    return true ;
}

bool Variant::SetFloat(float val)
{
    if(Type == VAR_UNKNOWN)
    {
        Type = VAR_FLOAT ;
    }

    if(Type != VAR_FLOAT)
        return false ;

    Data.val = 0 ;
    Data.f32 = val ;
    return true ;
}

bool Variant::SetDouble(double val)
{
    if(Type == VAR_UNKNOWN)
    {
        Type = VAR_DOUBLE ;
    }

    if(Type != VAR_DOUBLE)
        return false ;

    Data.val = 0 ;
    Data.f64 = val ;
    return true ;
}

bool Variant::SetString(const char * val)
{
    if(Type == VAR_UNKNOWN)
    {
        Type = VAR_STRING ;
    }

    if(Type != VAR_STRING)
        return false ;

    char * str = Data.str ;
    if(str != NULL)
    {
        ::free(str) ;
    }

    Length = 0 ;
    Data.val = 0 ;

    if(val == NULL)
        return true ;

    int length = ::strlen(val) + 1 ;
    char * buffer = (char *)malloc(length) ;
    if(buffer == NULL)
        return false ;

    memcpy(buffer , val , length) ;

    Length = length ;
    Data.str = buffer ;
    return true ;
}

bool Variant::SetString(const std::string& val)
{
    return SetString(val.c_str()) ;
}

bool Variant::SetRaw(const void * val , int len)
{
    if(Type == VAR_UNKNOWN)
    {
        Type = VAR_RAW ;
    }

    if(Type != VAR_RAW)
        return false ;

    Length = 0 ;
    Data.val = 0 ;

    if(val == NULL || len <= 0)
        return true ;

    char * buffer = (char *)malloc(len) ;
    if(buffer == NULL)
        return false ;

    memcpy(buffer , val , len) ;

    Length = len ;
    Data.raw = buffer ;
    return true ;
}

bool Variant::SetMap(const Map& map)
{
    if(Type == VAR_UNKNOWN)
    {
        Type = VAR_MAP ;
    }

    if(Type != VAR_MAP)
        return false ;

    Length = 0 ;
    Data.val = 0 ;

    Map * cont = new Map() ;
    *cont =  map ;

    Data.raw = cont ;
    return true ;
}

bool Variant::SetList(const List& list)
{    
    if(Type == VAR_UNKNOWN)
    {
        Type = VAR_LIST ;
    }

    if(Type != VAR_LIST)
        return false ;

    List * old = (List *)Data.raw ;
    if(old != NULL)
    {
        delete old ;
    }

    Length = 0 ;
    Data.val = 0 ;

    List * cont = new List() ;
    *cont =  list ;

    Data.raw = cont ;
    return true ;
}

bool Variant::GetBool(bool& val) const
{
    if(Type != VAR_BOOL)
        return false ;

    val = Data.bv ;
    return true ;
}

bool Variant::GetInt8(int8_t& val) const
{
    if(Type != VAR_INT8)
        return false ;

    val = Data.i8 ;
    return true ;
}

bool Variant::GetUInt8(uint8_t& val) const
{
    if(Type != VAR_UINT8)
        return false ;

    val = Data.u8 ;
    return true ;
}

bool Variant::GetInt16(int16_t& val) const
{
    if(Type != VAR_INT16)
        return false ;

    val = Data.i16 ;
    return true ;
}

bool Variant::GetUInt16(uint16_t& val) const
{
    if(Type != VAR_UINT16)
        return false ;

    val = Data.u16 ;
    return true ;
}

bool Variant::GetInt32(int32_t& val) const
{
    if(Type != VAR_INT32)
        return false ;

    val = Data.i32 ;
    return true ;
}

bool Variant::GetUInt32(uint32_t& val) const
{
    if(Type != VAR_UINT32)
        return false ;

    val = Data.u32 ;
    return true ;
}

bool Variant::GetInt64(int64_t& val) const
{
    if(Type != VAR_INT64)
        return false ;

    val = Data.i64 ;
    return true ;
}

bool Variant::GetUInt64(uint64_t& val) const
{
    if(Type != VAR_UINT64)
        return false ;

    val = Data.u64 ;
    return true ;
}

bool Variant::GetFloat(float& val) const
{
    if(Type != VAR_FLOAT)
        return false ;

    val = Data.f32 ;
    return true ;
}

bool Variant::GetDouble(double& val) const
{
    if(Type != VAR_DOUBLE)
        return false ;

    val = Data.f64 ;
    return true ;
}

bool Variant::GetString(std::string& val) const
{
    if(Type != VAR_STRING && Type != VAR_RAW)
        return false ;

    val.clear() ;
    if(Data.str != NULL)
    {
        //val = Data.str ;
        val.assign(Data.str , Length) ;
    }
    
    return true ;
}

bool Variant::GetRaw(void * val , size_t & len) const
{
    if(Type != VAR_RAW)
        return false ;

    if(len < (int)Length || val == NULL || Data.raw == NULL)
        return false ;

    memcpy(val , Data.raw , Length) ;
    len = Length ;    
    return true ;
}

bool Variant::GetRaw(Raw& raw) const
{
    raw.Clear() ;
    const void * val = NULL ;
    size_t size = 0 ;

    if(RefRaw(val , size) == false)
        return false ;

    if(raw.Copy(val , size) == false)
        return false ;

    return true ;
}

bool Variant::GetMap(Map& map) const
{
    if(Type != VAR_MAP)
        return false ;

    if(Data.raw == NULL)
        return false ;

    Map * cont = (Map *)Data.raw ;
    map = *cont ;
    return true ;
}

bool Variant::GetList(List& list) const
{
    if(Type != VAR_LIST)
        return false ;

    if(Data.raw == NULL)
        return false ;

    List * cont = (List *)Data.raw ;
    list = *cont ;
    return true ;
}

bool Variant::RefString(const char *& str , size_t& len) const
{
    str = NULL ;
    len = 0 ;

    if(Type != VAR_STRING && Type != VAR_RAW)
        return false ;

    str = Data.str ;
    len = Length ;
    
    return true ;
}

bool Variant::RefRaw(const void *& val , size_t& len) const
{
    val = NULL ;
    len = 0 ;

    if(Type != VAR_RAW)
        return false ;

    val = Data.raw ;
    len = Length ;
    
    return true ;
}

bool Variant::RefMap(const Map *& map) const
{
    map = NULL ;
   if(Type != VAR_MAP)
        return false ;

    if(Data.raw == NULL)
        return false ;

    map = (Map *)Data.raw ;
    return true ;
}

bool Variant::RefList(const List *& list) const
{
    list = NULL ;
    if(Type != VAR_LIST)
        return false ;

    if(Data.raw == NULL)
        return false ;

    list = (List *)Data.raw ;
    return true ;
}
bool Variant::RefTable(const Table *& table) const
{
	table = NULL;
	if (Type != VAR_TABLE)
		return false;

	if (Data.raw == NULL)
		return false;

	table = (Table *)Data.raw;
	return true;
}
Variant& Variant::operator=(bool val)
{
    SetBool(val) ;
    return (*this) ;
}

Variant& Variant::operator=(int8_t val)
{
    SetInt8(val) ;
    return (*this) ;
}

Variant& Variant::operator=(uint8_t val)
{
    SetUInt8(val) ;
    return (*this) ;
}

Variant& Variant::operator=(int16_t val)
{
    SetInt16(val) ;
    return (*this) ;
}

Variant& Variant::operator=(uint16_t val)
{
    SetUInt16(val) ;
    return (*this) ;
}

Variant& Variant::operator=(int32_t val)
{
    SetInt32(val) ;
    return (*this) ;
}

Variant& Variant::operator=(uint32_t val)
{
    SetUInt32(val) ;
    return (*this) ;
}

Variant& Variant::operator=(int64_t val)
{
    SetInt64(val) ;
    return (*this) ;
}

Variant& Variant::operator=(uint64_t val)
{
    SetUInt64(val) ;
    return (*this) ;
}

Variant& Variant::operator=(float val)
{
    SetFloat(val) ;
    return (*this) ;
}

Variant& Variant::operator=(double val)
{
    SetDouble(val) ;
    return (*this) ;
}


Variant& Variant::operator=(const char * val)
{
    SetString(val) ;
    return (*this) ;
}

Variant& Variant::operator=(const std::string& val)
{
    SetString(val) ;
    return (*this) ;
}

Variant& Variant::operator=(const Map& map)
{
    SetMap(map) ;
    return (*this) ;
}

Variant& Variant::operator=(const List& list)
{
    SetList(list);
    return (*this) ;
}

Variant& Variant::operator=(const VariantRaw& raw)
{
    SetRaw(raw.Data , raw.Length) ;
    return (*this) ;
}

Variant& Variant::operator=(const Variant& var)
{
    Assign(var) ;
    return (*this) ;
}


Variant::operator bool() const
{
    if(Type != VAR_BOOL)
        return false ;

    return Data.bv ;
}

Variant::operator int8_t() const
{
    if(Type != VAR_INT8)
        return 0 ;

    return Data.i8 ;
}

Variant::operator uint8_t() const
{
    if(Type != VAR_UINT8)
        return 0 ;

    return Data.u8 ;
}

Variant::operator int16_t() const
{
    if(Type != VAR_INT16)
        return 0 ;

    return Data.i16 ;
}

Variant::operator uint16_t() const
{
    if(Type != VAR_UINT16)
        return 0 ;

    return Data.u16 ;
}

Variant::operator int32_t() const
{
    if(Type != VAR_INT32)
        return 0 ;

    return Data.i32 ;
}

Variant::operator uint32_t() const
{
    if(Type != VAR_UINT32)
        return 0 ;

    return Data.u32 ;
}

Variant::operator int64_t() const
{
    if(Type != VAR_INT64)
        return 0 ;

    return Data.i64 ;
}

Variant::operator uint64_t() const
{
    if(Type != VAR_UINT64)
        return 0 ;

    return Data.u64 ;
}

Variant::operator float() const
{
    if(Type != VAR_FLOAT)
        return 0 ;

    return Data.f32 ;
}

Variant::operator double() const
{
    if(Type != VAR_DOUBLE)
        return 0 ;

    return Data.f64 ;
}

Variant::operator const Variant::Map& () const
{
    if(Type != VAR_MAP || Data.raw == NULL)
        return VariantMap::EMPTY ;

    const Variant::Map * map = (const Variant::Map *)(Data.raw) ;

    return *map ;
}
Variant::operator const Variant::Table& () const
{
	if (Type != VAR_TABLE || Data.raw == NULL)
		return VariantTable::EMPTY;

	const Variant::Table * table = (const Variant::Table *)(Data.raw);
	return *table;
}
Variant::operator const Variant::List& () const
{
    if(Type != VAR_LIST || Data.raw == NULL)
        return VariantList::EMPTY ;

    const Variant::List * list = (const Variant::List *)(Data.raw) ;

    return *list ;
}

const Variant Variant::EMPTY ;

}
}


